#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

using ll = long;

class segtree {
	vector<ll> &arr;
	vector<ll> amax;
	vector<ll> add;
	vector<ll> change;
	vector<bool> update;

	void addlazy(int i, ll v)
	{
		amax[i] += v;
		add[i] += v;
	}

	void chglazy(int i, ll v)
	{
		amax[i] = v;
		change[i] = v;
		update[i] = true;
		add[i] = 0;
	}

	void up(int i)
	{
		amax[i] = max(amax[i << 1], amax[(i << 1) | 1]);
	}

	void down(int i)
	{
		if (update[i]) {
			chglazy(i << 1, change[i]);
			chglazy((i << 1) | 1, change[i]);
			update[i] = false;
		}

		if (add[i]) {
			addlazy(i << 1, add[i]);
			addlazy((i << 1) | 1, add[i]);
			add[i] = 0;
		}
	}

	void build(int l, int r, int i)
	{
		if (l == r) {
			amax[i] = arr[l];
		} else {
			int mid = (l + r) >> 1;
			build(l, mid, i << 1);
			build(mid + 1, r, (i << 1) | 1);
                        up(i);
		}
	}

    public:
	void addv(int jobl, int jobr, ll v, int l, int r, int i)
	{
		if (jobl <= l && r <= jobr) {
			addlazy(i, v);
			return;
		}
		down(i);

		int mid = (l + r) >> 1;
		if (jobl <= mid) {
			addv(jobl, jobr, v, l, mid, i << 1);
		}
		if (mid < jobr) {
			addv(jobl, jobr, v, mid + 1, r, (i << 1) | 1);
		}

		up(i);
	}

	void changev(int jobl, int jobr, ll v, int l, int r, int i)
	{
		if (jobl <= l && r <= jobr) {
			chglazy(i, v);
			return;
		}
		down(i);

		int mid = (l + r) >> 1;
		if (jobl <= mid) {
			changev(jobl, jobr, v, l, mid, i << 1);
		}
		if (mid < jobr) {
			changev(jobl, jobr, v, mid + 1, r, (i << 1) | 1);
		}

		up(i);
	}

	ll query(int jobl, int jobr, int l, int r, int i)
	{
		if (jobl <= l && r <= jobr) {
			return amax[i];
		}
		down(i);

		ll ans = INT64_MIN;
		int mid = (l + r) >> 1;
		if (jobl <= mid) {
			ans = max(ans, query(jobl, jobr, l, mid, i << 1));
		}
		if (mid < jobr) {
			ans = max(ans, query(jobl, jobr, mid + 1, r, (i << 1) | 1));
		}

		return ans;
	}

    public:
	segtree(vector<ll> &arr) : arr(arr), amax(arr.size() << 2, 0), add(arr.size() << 2), change(arr.size() << 2, 0), update(arr.size() << 2, false)
	{
		build(1, arr.size() - 1, 1);
	}
};

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m;
	cin >> n >> m;
	vector<ll> arr(n + 1, 0);
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}
	segtree sgt(arr);

	ll v = 0;
	for (int i = 0, op, l, r; i < m; i++) {
		cin >> op >> l >> r;
		if (op == 1) {
			cin >> v;
			sgt.changev(l, r, v, 1, n, 1);
		} else if (op == 2) {
			cin >> v;
			sgt.addv(l, r, v, 1, n, 1);
		} else {
			cout << sgt.query(l, r, 1, n, 1) << '\n';
		}
	}

	return 0;
}
/*
24 4
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 3 4 7
2 1 3 9
2 2 2 1
3 1 24
*/